package apps.AfterDlcs.afterDlcsBL.warSand;

import apps.AfterDlcs.afterDlcsBL.Event;
import apps.AfterDlcs.afterDlcsBL.Keys;
import apps.AfterDlcs.afterDlcsBL.buff.Buff;
import apps.AfterDlcs.afterDlcsBL.hero.Hero;
import apps.AfterDlcs.afterDlcsBL.hero.HeroBL;
import apps.AfterDlcs.afterDlcsBL.hero.HeroKeys;
import apps.AfterDlcs.afterDlcsBL.world.WorldBL;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class WarSand
{
    Map<String,List<Hero>> teamList=new HashMap<>();
    int locationX,locationY,worldID;

    public static Map<String ,WarSand> warSandMap=new HashMap<>();

    public static WarSand getWarSand(int worldID,int locationX,int locationY)
    {
        String key=worldID+"_"+locationX+"_"+locationY;
        WarSand warSand=warSandMap.get(key);
        if(warSand==null)
        {
            warSand=new WarSand(worldID,locationX,locationY);
            warSandMap.put(key,warSand);
            warSand.initWarSand();
        }
        return warSand;
    }

    WarSand(int worldID,int locationX,int locationY)
    {
        this.locationX=locationX;
        this.locationY=locationY;
        this.worldID=worldID;
    }

    void initWarSand()
    {
        int nowID= WorldBL.getNowHeroID(worldID);
        for(int id=WorldBL.START_HERO_ID;id<=nowID;id++)
        {
            addHero(new Hero(worldID,id));
        }
    }

    public static void handleWorldEvent(int worldID,Event event)
    {
        for(String key:warSandMap.keySet())
        {
            WarSand warSand=warSandMap.get(key);
            if(warSand.worldID==worldID)
            {
                warSand.handleEvent(event);
            }
        }
    }

    public void handleEvent(Event event)
    {
        for(event.eventTurn=1;event.eventTurn<=event.maxTurn;event.eventTurn++)
        {
            if(!event.goOn) return;
            if(event.eventTurn%2!=1) handleEventBackward(event);
            else handleEventForward(event);
        }
    }

    public void handleEventForward(Event event)
    {
        List<Hero> heroList=new ArrayList<>();
        heroList.add(event.mainHero);
        heroList.addAll(getTeamMates(event.mainHero));
        heroList.addAll(getEnemys(event.mainHero));
        for(int n=Buff.MAX_BUFF_LEVEL;n>=0;n--)
        {
            for(Hero hero:heroList)
                for(Buff buff:hero.buffMap.get(n))
                {
                    if(event.goOn)
                    {
                        buff.handleEvent(event);
                    }
                    else return;
                }
        }
    }

    public void handleEventBackward(Event event)
    {
        List<Hero> heroList=new ArrayList<>();
        heroList.add(event.mainHero);
        heroList.addAll(getEnemys(event.mainHero));
        heroList.addAll(getTeamMates(event.mainHero));
        for(int n=0;n<=Buff.MAX_BUFF_LEVEL;n++)
        {
            for(Hero hero:heroList)
                for(Buff buff:hero.buffMap.get(n))
                {
                    if(!event.goOn)return;
                    buff.handleEvent(event);
                }
        }
    }


    public List<Hero> getTeamMates(Hero hero)
    {
        List<Hero> heroes=getAllTeamMates(hero);
        for(Hero onehero:getAllTeamMates(hero))
        {
            if(!"1".equals(onehero.getValueByEvent(HeroKeys.ALIVE)))
            {
                heroes.remove(onehero);
            }
        }
        return heroes;
    }

    public List<Hero> getEnemys(Hero hero)
    {
        List<Hero> heroes=getAllEnemys(hero);
        for(Hero onehero:getAllEnemys(hero))
        {
            if(!"1".equals(onehero.getValueByEvent(HeroKeys.ALIVE)))
            {
                heroes.remove(onehero);
            }
        }
        return heroes;
    }

    public List<Hero> getAllTeamMates(Hero hero)
    {
        List<Hero> heroes=new ArrayList<>();
        for(String teamS:teamList.keySet())
        {
            List<Hero> team=teamList.get(teamS);
            if(team.contains(hero))
            {
                heroes.addAll(team);
                heroes.remove(hero);
            }
        }
        return heroes;
    }

    public List<Hero> getAllEnemys(Hero hero)
    {
        List<Hero> heroes=new ArrayList<>();
        for(String teamS:teamList.keySet())
        {
            List<Hero> team=teamList.get(teamS);
            if(!team.contains(hero))
            {
                heroes.addAll(team);
            }
        }
        return heroes;
    }



    public boolean containHero(Hero hero)
    {
        for(String teamS:teamList.keySet())
        {
            List<Hero> team=teamList.get(teamS);
            if(team.contains(hero))
            {
                return true;
            }
        }
        return false;
    }

    public void removeHero(Hero hero)
    {
        for(String teamS:teamList.keySet())
        {
            List<Hero> team=teamList.get(teamS);
            if(team.contains(hero))
            {
                team.remove(hero);
            }
        }
    }

    public void addHero(Hero hero)
    {
        if(containHero(hero)) return;
        int heroX=Integer.parseInt(HeroBL.getHeroValue(worldID,hero.heroID, Keys.LOCATION_X,"0",false));
        int heroY=Integer.parseInt(HeroBL.getHeroValue(worldID,hero.heroID, Keys.LOCATION_Y,"0",false));
        if(heroX==locationX&&heroY==locationY)
        {
            String heroGroup=HeroBL.getHeroValue(worldID,hero.heroID, HeroKeys.CITY,"0",false);
            if(teamList.containsKey(heroGroup))
            {
                teamList.get(heroGroup).add(Hero.getHero(worldID,hero.heroID));
            }
            else
            {
                List<Hero> heroes=new ArrayList<>();
                heroes.add(Hero.getHero(worldID,hero.heroID));
                teamList.put(heroGroup,heroes);
            }
        }
    }
}
